using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using GeYiHome.Domain.Entities;
using GeYiHome.Domain.Specification.SpecAbstract;
using GeYiHome.PublicLibrary;

namespace GeYiHome.Db.IDbBase
{
   public interface IDataBase
    {
        int SaveChanges();

        /// <summary>
        /// 获取单个实体对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TKey">The type of the t key.</typeparam>
        /// <param name="id">The identifier.</param>
        /// <returns>TEntity.</returns>
        TEntity Get<TEntity, TKey>(TKey id) where TEntity : BaseEntity;

        /// <summary>
        /// 获取所有对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <returns>IQueryable&lt;TEntity&gt;.</returns>
        IQueryable<TEntity> GetAll<TEntity>() where TEntity : BaseEntity;

        /// <summary>
        /// 获取所有符合条件的对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="specification">The specification.</param>
        /// <returns>IQueryable&lt;TEntity&gt;.</returns>
        IQueryable<TEntity> GetAllMatching<TEntity>(ISpecification<TEntity> specification)
            where TEntity : BaseEntity;

        /// <summary>
        /// 分页获取对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TK">The type of the tk.</typeparam>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="specification">The specification.</param>
        /// <param name="orderByExpression">The order by expression.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns>DataPageList&lt;TEntity&gt;.</returns>
        DataPageList<TEntity> GetPageList<TEntity, TK>(int pageIndex,
            int pageSize, ISpecification<TEntity> specification, Expression<Func<TEntity, TK>> orderByExpression,
            SortEnum sortOrder) where TEntity : BaseEntity;

        /// <summary>
        /// 分页获取对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TK">The type of the tk.</typeparam>
        /// <param name="entities">The entities.</param>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="specification">The specification.</param>
        /// <param name="orderByExpression">The order by expression.</param>
        /// <param name="sortOrder">The sort order.</param>
        /// <returns>DataPageList&lt;TEntity&gt;.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">null</exception>
        DataPageList<TEntity> GetPageList<TEntity, TK>(IQueryable<TEntity> entities, int pageIndex,
            int pageSize, ISpecification<TEntity> specification, Expression<Func<TEntity, TK>> orderByExpression,
            SortEnum sortOrder) where TEntity : BaseEntity;

        /// <summary>
        /// 修改对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Modify<TEntity>(TEntity entity) where TEntity : BaseEntity;

        /// <summary>
        /// 修改对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entities">The entities.</param>
        void Modify<TEntity>(IEnumerable<TEntity> entities) where TEntity : BaseEntity;

        /// <summary>
        /// 按条件修改部分字段
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="specification">The specification.</param>
        /// <param name="value">The value.</param>
        void Modify<TEntity>(ISpecification<TEntity> specification,
            Expression<Func<TEntity, TEntity>> value) where TEntity : BaseEntity, new();
        /// <summary>
        /// 根据主键删除
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <typeparam name="TKey">The type of the t key.</typeparam>
        /// <param name="id">The identifier.</param>
        void Remove<TEntity,TKey>(TKey id) where TEntity : BaseEntity;
        /// <summary>
        /// 删除对象
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Remove<TEntity>(TEntity entity) where TEntity : BaseEntity;

        /// <summary>
        /// 按条件删除
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="specification">The specification.</param>
        void Remove<TEntity>(ISpecification<TEntity> specification) where TEntity : BaseEntity;

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entities">The entities.</param>
        void Remove<TEntity>(IEnumerable<TEntity> entities) where TEntity : BaseEntity;

        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entities">The entities.</param>
        void Add<TEntity>(IEnumerable<TEntity> entities) where TEntity : BaseEntity;

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="entity">The entity.</param>
        void Add<TEntity>(TEntity entity) where TEntity : BaseEntity;

        /// <summary>
        /// 执行返回查询语句
        /// </summary>
        /// <typeparam name="TEntity">The type of the t entity.</typeparam>
        /// <param name="sqlQuery">The SQL query.</param>
        /// <param name="parameters">The parameters.</param>
        /// <returns>IEnumerable&lt;TEntity&gt;.</returns>
        IEnumerable<TEntity> ExecuteQuery<TEntity>(string sqlQuery, params object[] parameters);

        /// <summary>
        /// 执行sql语句
        /// </summary>
        /// <param name="sqlCommand"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        int ExecuteCommand(string sqlCommand, params object[] parameters);
    }
}
